#pragma once
#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<string>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<signal.h>

using namespace std;

//这段代码是一个用于将程序转换为守护进程（daemon）的C++函数。守护进程是一种在后台运行的特殊进程，通常用于执行长期的任务或服务
//也就是说就算我们云平台退出了，这个程序依然在服务器上跑，除非我们手动关闭

const string nullfile="/dev/null";
//这是一个特殊的文件，它会丢弃所有写入其中的数据，并且从它读取会立即返回文件结束标志。

void Daemon(const string &cwd="")
{
    //1，忽略其他异常信号：
    signal(SIGCLD,SIG_IGN);
    signal(SIGPIPE,SIG_IGN);
    signal(SIGSTOP,SIG_IGN);

    //2,将自己变为一个独立的会话：
    if(fork()>0)//通过fork()创建一个新的子进程。如果fork()返回值大于0（即父进程），则退出父进程，留下子进程继续执行。此时子进程会托孤给bash进程，资源的释放也交给bash进程管理，也就是说守护进程本质是一种孤儿进程
        exit(0);
    setsid();//创建一个新的会话，并使子进程成为该会话的领头进程。这使得守护进程与控制终端无关。

    //3，更改当前调用进程的工作目录
    if(!cwd.empty())//如果我们显式传递了工作目录就按照我们的目录
    {
        chdir(cwd.c_str());
    }

    //4，标准输入，标准输出，标准错误重定向到/dev/null
    int fd=open(nullfile.c_str(),O_RDWR);
    if(fd>0)
    {
        dup2(fd,0);
        dup2(fd,1);
        dup2(fd,2);
        close(fd);
    }
//将输出重定向到 /dev/null 是一种控制输出、提高程序健壮性和安全性的常用方法。对于守护进程来说，这种做法有助于确保它们在后台安静地运行，不会对用户或其他程序产生干扰。

//通过这些步骤，程序被转换为守护进程，它在后台运行，不与任何终端相关联，并且其标准输入、输出和错误都被重定向到/dev/null，使得守护进程不会在终端上产生任何输出。
}